import * as THREE from 'three';

export default function createPointCloudSystem(models) {
    const BASE_SIZE = 10;
    const HIGHLIGHT_COLOR = new THREE.Color(0xff0000);

    // 创建共享几何体和材质
    const geometry = new THREE.SphereGeometry(BASE_SIZE, 16, 16);
    const material = createPointMaterial();

    // 主实例化网格
    let instancedMesh = null;
    let instanceColors = null;

    // 创建点材质
    function createPointMaterial() {
        const mat = new THREE.MeshBasicMaterial({
            vertexColors: true,
            transparent: true
        });
        // 实现彩色渲染
        mat.onBeforeCompile = (shader) => {
            shader.vertexShader = shader.vertexShader.replace(
                '#include <color_vertex>',
                'vColor = color;'
            );
        };
        return mat;
    }

    // 设置点云数据
    function setUpPoints(points) {
        // 清理旧网格
        if (instancedMesh) {
            models.remove(instancedMesh);
            instancedMesh = null;
        }
        // 创建新网格
        instancedMesh = new THREE.InstancedMesh(geometry, material, points.length);
        instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
        instancedMesh.userData = {
            isPoint: true,
            points: {},
            highlightPoints: []
        };
        models.add(instancedMesh);

        // 初始化点数据
        instanceColors = new Float32Array(points.length * 3);
        const colorAttribute = new THREE.InstancedBufferAttribute(
            instanceColors, 3, false, 1
        );
        colorAttribute.setUsage(THREE.DynamicDrawUsage);
        geometry.setAttribute('color', colorAttribute);

        const dummy = new THREE.Object3D();
        const color = new THREE.Color();

        points.forEach((point, index) => {
            updatePointData(index, point, dummy, color);
            instancedMesh.userData.points[index] = { ...point };
        });
    }

    // 更新单个点数据
    function updatePointData(index, point, dummy, color) {
        // 设置位置和缩放
        dummy.position.set(point.x || 0, point.y || 0, point.z || 0);
        dummy.scale.setScalar(point.size || 1.0);
        dummy.updateMatrix();
        instancedMesh.setMatrixAt(index, dummy.matrix);

        // 设置颜色
        // color.setHex(point.color || Math.random() * 0xffffff);
        color.setHex(point.color || 0xA9A6AB);
        instanceColors[index * 3] = color.r;
        instanceColors[index * 3 + 1] = color.g;
        instanceColors[index * 3 + 2] = color.b;

        // 标记需要更新
        instancedMesh.instanceMatrix.needsUpdate = true;
        geometry.attributes.color.needsUpdate = true;
    }

    // 更新点
    function updatePoint(index, point) {
        if (!instancedMesh?.userData.points[index]) return false;

        Object.assign(instancedMesh.userData.points[index], point);
        updatePointData(index, point, new THREE.Object3D(), new THREE.Color());
        return true;
    }

    /**
     * 设置穿透模式
     * @param {*} bool 
     */
    function setPointDepth(bool) {
        material.depthWrite = !bool;
        material.opacity = bool ? 0.5 : 1.0;
        material.needsUpdate = true;  // 确保材质更新
    }

    // 设置点可见性
    function setVisiblePoint(indices, hide = true) {
        if (!instancedMesh) return;

        const nullMatrix = new THREE.Matrix4();
        const dummy = new THREE.Object3D();

        indices.forEach(index => {
            if (!instancedMesh.userData.points[index]) return;

            instancedMesh.userData.points[index].hide = hide;

            if (hide) {
                instancedMesh.setMatrixAt(index, nullMatrix);
            } else {
                const point = instancedMesh.userData.points[index];
                dummy.position.set(point.x || 0, point.y || 0, point.z || 0);
                dummy.scale.setScalar(point.size || 1.0);
                dummy.updateMatrix();
                instancedMesh.setMatrixAt(index, dummy.matrix);
            }
        });

        instancedMesh.instanceMatrix.needsUpdate = true;
    }

    // 获取当前世界坐标
    function getWorldPosition(instanceId) {
        // 1. 获取实例的局部变换矩阵
        const instanceMatrix = new THREE.Matrix4();
        instancedMesh.getMatrixAt(instanceId, instanceMatrix);

        // 2. 创建临时对象并应用实例变换
        const dummy = new THREE.Object3D();
        dummy.applyMatrix4(instanceMatrix);

        // 3. 将临时对象添加到与Group相同的变换层级
        const tempParent = new THREE.Group();

        // 复制Group的变换（包括quaternion旋转）
        tempParent.position.copy(instancedMesh.parent.position);
        tempParent.quaternion.copy(instancedMesh.parent.quaternion);
        tempParent.scale.copy(instancedMesh.parent.scale);

        tempParent.add(dummy);

        // 4. 更新世界矩阵
        tempParent.updateMatrixWorld(true);

        // 5. 获取世界位置
        const worldPosition = new THREE.Vector3();
        dummy.getWorldPosition(worldPosition);

        return worldPosition;
    }


    // 处理点击事件
    function handlePointClick(index, isMultiple) {
        console.log("点击了点", index, isMultiple)
        if (!instancedMesh) return;
        // 处理点击
        if (!isMultiple) {
            resetHighlight();
        }
        if (Number.isFinite(index)) {
            setHighlight(index);
        }

    }

    // 设置高亮点
    function setHighlight(index) {
        console.log(index)
        const highlightPoints = instancedMesh.userData.highlightPoints;
        const colors = geometry.attributes.color.array;

        highlightPoints.push({
            index,
            r: colors[index * 3],
            g: colors[index * 3 + 1],
            b: colors[index * 3 + 2]
        });

        colors[index * 3] = HIGHLIGHT_COLOR.r;
        colors[index * 3 + 1] = HIGHLIGHT_COLOR.g;
        colors[index * 3 + 2] = HIGHLIGHT_COLOR.b;

        geometry.attributes.color.needsUpdate = true;
    }

    // 重置高亮
    function resetHighlight() {
        if (!instancedMesh) return
        const highlightPoints = instancedMesh.userData.highlightPoints;
        const colors = geometry.attributes.color.array;

        highlightPoints.forEach(item => {
            colors[item.index * 3] = item.r;
            colors[item.index * 3 + 1] = item.g;
            colors[item.index * 3 + 2] = item.b;
        });

        instancedMesh.userData.highlightPoints = [];
        geometry.attributes.color.needsUpdate = true;
    }

    // 完全清理
    function cleanup() {
        if (instancedMesh) {
            models.remove(instancedMesh);
            instancedMesh = null;
        }
        geometry.dispose();
        material.dispose();
    }

    return {
        setUpPoints,
        updatePoint,
        setVisiblePoint,
        handlePointClick,
        resetHighlight,
        cleanup,
        setPointDepth,
        getWorldPosition,
        get points() {
            return instancedMesh?.userData.points || {};
        }
    };
}